#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
macOS 网络配置备份工具
备份所有网络相关配置，包括网络接口、DNS、路由、代理等
"""

import subprocess
import json
import os
import datetime
import shutil
from pathlib import Path

class NetworkBackup:
    def __init__(self, backup_dir="network_backup"):
        self.backup_dir = Path(backup_dir)
        self.timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        self.backup_path = self.backup_dir / f"backup_{self.timestamp}"
        
    def create_backup_directory(self):
        """创建备份目录"""
        self.backup_path.mkdir(parents=True, exist_ok=True)
        print(f"创建备份目录: {self.backup_path}")
        
    def run_command(self, command):
        """执行系统命令并返回结果"""
        try:
            result = subprocess.run(command, shell=True, capture_output=True, text=True)
            return result.stdout, result.stderr, result.returncode
        except Exception as e:
            return "", str(e), 1
    
    def backup_network_interfaces(self):
        """备份网络接口配置"""
        print("备份网络接口配置...")
        
        # 获取网络接口信息
        stdout, stderr, code = self.run_command("ifconfig -a")
        if code == 0:
            with open(self.backup_path / "ifconfig.txt", "w") as f:
                f.write(stdout)
        
        # 获取网络服务配置
        stdout, stderr, code = self.run_command("networksetup -listallnetworkservices")
        if code == 0:
            with open(self.backup_path / "network_services.txt", "w") as f:
                f.write(stdout)
        
        # 备份每个网络服务的详细配置
        services = stdout.strip().split('\n')[1:]  # 跳过第一行标题
        for service in services:
            if service.strip():
                # 获取服务详细信息
                stdout, stderr, code = self.run_command(f"networksetup -getinfo \"{service}\"")
                if code == 0:
                    with open(self.backup_path / f"service_{service.replace(' ', '_')}.txt", "w") as f:
                        f.write(stdout)
    
    def backup_dns_config(self):
        """备份DNS配置"""
        print("备份DNS配置...")
        
        # 获取DNS服务器
        stdout, stderr, code = self.run_command("scutil --dns")
        if code == 0:
            with open(self.backup_path / "dns_config.txt", "w") as f:
                f.write(stdout)
        
        # 获取resolv.conf
        stdout, stderr, code = self.run_command("cat /etc/resolv.conf")
        if code == 0:
            with open(self.backup_path / "resolv_conf.txt", "w") as f:
                f.write(stdout)
    
    def backup_routing_table(self):
        """备份路由表"""
        print("备份路由表...")
        
        # 获取路由表
        stdout, stderr, code = self.run_command("netstat -rn")
        if code == 0:
            with open(self.backup_path / "routing_table.txt", "w") as f:
                f.write(stdout)
        
        # 获取ARP表
        stdout, stderr, code = self.run_command("arp -a")
        if code == 0:
            with open(self.backup_path / "arp_table.txt", "w") as f:
                f.write(stdout)
    
    def backup_proxy_settings(self):
        """备份代理设置"""
        print("备份代理设置...")
        
        # 获取系统代理设置
        stdout, stderr, code = self.run_command("networksetup -getwebproxy \"Wi-Fi\"")
        if code == 0:
            with open(self.backup_path / "web_proxy.txt", "w") as f:
                f.write(stdout)
        
        stdout, stderr, code = self.run_command("networksetup -getsecurewebproxy \"Wi-Fi\"")
        if code == 0:
            with open(self.backup_path / "secure_web_proxy.txt", "w") as f:
                f.write(stdout)
        
        stdout, stderr, code = self.run_command("networksetup -getsocksfirewallproxy \"Wi-Fi\"")
        if code == 0:
            with open(self.backup_path / "socks_proxy.txt", "w") as f:
                f.write(stdout)
    
    def backup_firewall_settings(self):
        """备份防火墙设置"""
        print("备份防火墙设置...")
        
        # 获取防火墙状态
        stdout, stderr, code = self.run_command("sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate")
        if code == 0:
            with open(self.backup_path / "firewall_state.txt", "w") as f:
                f.write(stdout)
        
        # 获取防火墙规则
        stdout, stderr, code = self.run_command("sudo /usr/libexec/ApplicationFirewall/socketfilterfw --listapps")
        if code == 0:
            with open(self.backup_path / "firewall_rules.txt", "w") as f:
                f.write(stdout)
    
    def backup_network_preferences(self):
        """备份网络偏好设置"""
        print("备份网络偏好设置...")
        
        # 备份网络偏好设置文件
        prefs_path = Path.home() / "Library/Preferences/SystemConfiguration"
        if prefs_path.exists():
            shutil.copytree(prefs_path, self.backup_path / "SystemConfiguration", 
                          ignore=shutil.ignore_patterns("*.lock"))
    
    def backup_hosts_file(self):
        """备份hosts文件"""
        print("备份hosts文件...")
        
        stdout, stderr, code = self.run_command("cat /etc/hosts")
        if code == 0:
            with open(self.backup_path / "hosts.txt", "w") as f:
                f.write(stdout)
    
    def create_restore_script(self):
        """创建恢复脚本"""
        print("创建恢复脚本...")
        
        restore_script = f"""#!/bin/bash
# macOS 网络配置恢复脚本
# 备份时间: {self.timestamp}

echo "开始恢复网络配置..."

# 恢复hosts文件
if [ -f "hosts.txt" ]; then
    echo "恢复hosts文件..."
    sudo cp hosts.txt /etc/hosts
fi

# 恢复网络偏好设置
if [ -d "SystemConfiguration" ]; then
    echo "恢复网络偏好设置..."
    sudo cp -r SystemConfiguration/* ~/Library/Preferences/SystemConfiguration/
fi

# 重启网络服务
echo "重启网络服务..."
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

echo "网络配置恢复完成！"
echo "请重启系统以确保所有设置生效。"
"""
        
        with open(self.backup_path / "restore.sh", "w") as f:
            f.write(restore_script)
        
        # 设置执行权限
        os.chmod(self.backup_path / "restore.sh", 0o755)
    
    def create_backup_info(self):
        """创建备份信息文件"""
        info = {
            "backup_time": self.timestamp,
            "backup_path": str(self.backup_path),
            "description": "macOS网络配置完整备份",
            "includes": [
                "网络接口配置",
                "DNS设置",
                "路由表",
                "代理设置",
                "防火墙设置",
                "网络偏好设置",
                "hosts文件"
            ],
            "restore_instructions": "运行 restore.sh 脚本恢复配置"
        }
        
        with open(self.backup_path / "backup_info.json", "w") as f:
            json.dump(info, f, indent=2, ensure_ascii=False)
    
    def record_redis_info(self):
        """记录Redis服务器信息（不进行连接测试）"""
        print("记录Redis服务器信息...")
        
        redis_host = "test-redis.oyumwu.clustercfg.apne1.cache.amazonaws.com"
        
        with open(self.backup_path / "redis_server_info.txt", "w") as f:
            f.write(f"目标Redis服务器信息:\n")
            f.write(f"主机: {redis_host}\n")
            f.write(f"记录时间: {datetime.datetime.now()}\n")
            f.write(f"\n注意: 此Redis服务器需要公钥认证\n")
            f.write(f"请先配置本地公钥后联系运维添加到白名单\n")
        
        print(f"✅ Redis服务器信息已记录: {redis_host}")
    
    def run_backup(self):
        """执行完整备份"""
        print("开始备份macOS网络配置...")
        print(f"备份目录: {self.backup_path}")
        
        self.create_backup_directory()
        self.backup_network_interfaces()
        self.backup_dns_config()
        self.backup_routing_table()
        self.backup_proxy_settings()
        self.backup_firewall_settings()
        self.backup_network_preferences()
        self.backup_hosts_file()
        self.record_redis_info()
        self.create_restore_script()
        self.create_backup_info()
        
        print(f"\n✅ 备份完成！")
        print(f"备份位置: {self.backup_path}")
        print(f"恢复方法: 进入备份目录，运行 ./restore.sh")
        print(f"备份信息: {self.backup_path}/backup_info.json")

if __name__ == "__main__":
    backup = NetworkBackup()
    backup.run_backup()
